package com.hzit.aspect;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.hzit.anno.RequiresPermissions;
import com.hzit.entity.LoginUser;
import com.hzit.enums.Logical;
import com.hzit.excep.NotPermissionException;
import com.hzit.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.var;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import sun.plugin.liveconnect.SecurityContextHelper;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 类名：
 * 作者：WF
 * 功能：
 */
@Aspect
@Component
public class PreAuthAspect {
	@Autowired
	private StringRedisTemplate redisTemplate;
	/**
	 * 环绕通知
	 *
	 * @param point
	 * @param permissions
	 * @return
	 * @throws Throwable
	 */
	@Around("@annotation(permissions)")
	public Object innerAround(ProceedingJoinPoint point, RequiresPermissions permissions) throws Throwable {
		//1. 得到方法上的权限串列表
		String[] myMethodPermissions = permissions.value();
		// 2. 得到当前登录用户的权限串列表
		List<String> permissionList = getPermissionsByToken();
		// 3. 判断方法前的注解中的权限串是否在上面的权限串列表中
		isExistPersion(myMethodPermissions,permissionList,permissions);
		return point.proceed();
	}

	/**
	 *
	 * @param myMethodPermissions 方法前的自定义注解RequirePermission中的value值
	 * @param permissionList 当前登录用户的权限串列表
	 */
	private void isExistPersion(String[] myMethodPermissions, List<String> permissionList,RequiresPermissions permissions) {
		boolean flag = true;
		for (String permission : myMethodPermissions) {
			Logical logical = permissions.logical();
			if(logical == Logical.AND){
				if(!permissionList.contains(permission)){
					throw new NotPermissionException("对不起,你没有访问此资源的权限!");
				}
				flag = false;
			}
			if(logical == Logical.OR){
				if(permissionList.contains(permission)){
					flag = false;
				}
			}
		}
		if(flag){
			throw new NotPermissionException("对不起,你没有访问此资源的权限!");
		}
	}

	private List<String> getPermissionsByToken() {
		// 1. 可以在任意位置得到当前请求对象
		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = requestAttributes.getRequest();
		// 2. 得到请求头Authorization信息
		String authorization = request.getHeader("Authorization");
		// 3. 得到token值
		String token = getToken(authorization);
		// 4. 解析token值

		Claims claims = JwtUtil.parseToken(token);

		String uuid = claims.get("user_key") + "";
		String redisKey = getKey(uuid);
		// 登录用户的字符串
		String loginUserStr = redisTemplate.opsForValue().get(redisKey);
		// 将上面的登录用户串转换为LoginUser对象
		LoginUser loginUser = JSON.parseObject(loginUserStr, LoginUser.class);
		// 得到当前登录用户的权限串列表
		List<String> permissions = loginUser.getPermissions();

		return permissions;
	}

	private String getKey(String uuid) {
		return "login_tokens:" + uuid;
	}

	private String getToken(String authorization) {
		if (authorization.startsWith("Bearer ")) {
			return authorization.replace("Bearer ", "");
		}
		return null;
	}

}
